﻿using Ardalis.GuardClauses;
using Domain.Todos.Events;
using SharedKernel;

namespace Domain.Todos;

public  class TodoItem : Entity<Guid>, IAggregateRoot
{
    /// <summary>
    /// EF Core 需要的无参构造函数
    /// </summary>
    protected TodoItem()
    {
    }

    /// <summary>
    /// 创建新的待办事项
    /// </summary>
    public TodoItem(
        Guid userId,
        string description,
        Priority priority,
        DateTime? dueDate,
        List<string>? labels,
        IDateTimeProvider dateTimeProvider)
    {
        UserId = Guard.Against.Default(userId);
        Description = Guard.Against.NullOrWhiteSpace(description);
        Priority = Guard.Against.EnumOutOfRange(priority);
        DueDate = dueDate;
        Labels = labels ?? [];
        IsCompleted = false;
        CreatedAt = Guard.Against.Null(dateTimeProvider).UtcNow;

        // 在聚合根内部触发领域事件
        Raise(new TodoItemCreatedEvent(Id, UserId, Description, Priority, DueDate, CreatedAt));
    }

    public Guid UserId { get; private set; }
    public string Description { get; private set; } = string.Empty;
    public DateTime? DueDate { get; private set; }
    public List<string> Labels { get; private set; } = [];
    public bool IsCompleted { get; private set; }
    public DateTime CreatedAt { get; private set; }
    public DateTime? CompletedAt { get; private set; }
    public Priority Priority { get; private set; }

    /// <summary>
    /// 完成待办事项
    /// </summary>
    public Result Complete(IDateTimeProvider dateTimeProvider)
    {
        if (IsCompleted)
        {
            return Result.Failure(TodoItemErrors.AlreadyCompleted);
        }

        IsCompleted = true;
        CompletedAt = dateTimeProvider.UtcNow;

        // 在聚合根内部触发领域事件
        Raise(new TodoItemCompletedEvent(Id, UserId, Description, CompletedAt.Value));

        return Result.Success();
    }

    /// <summary>
    /// 更新待办事项描述
    /// </summary>
    public void UpdateDescription(string description)
    {
        Description = Guard.Against.NullOrWhiteSpace(description);
    }

    /// <summary>
    /// 更新截止日期
    /// </summary>
    public void UpdateDueDate(DateTime? dueDate)
    {
        DueDate = dueDate;
    }

    /// <summary>
    /// 更新优先级
    /// </summary>
    public void UpdatePriority(Priority priority)
    {
        Priority = priority;
    }

    /// <summary>
    /// 添加标签
    /// </summary>
    public void AddLabel(string label)
    {
        Guard.Against.NullOrWhiteSpace(label);

        if (!Labels.Contains(label))
        {
            Labels.Add(label);
        }
    }

    /// <summary>
    /// 移除标签
    /// </summary>
    public void RemoveLabel(string label)
    {
        Labels.Remove(label);
    }

    /// <summary>
    /// 设置标签列表
    /// </summary>
    public void SetLabels(List<string>? labels)
    {
        Labels = labels ?? [];
    }

    /// <summary>
    /// 检查是否已过期
    /// </summary>
    public bool IsOverdue(IDateTimeProvider dateTimeProvider)
    {
        return DueDate.HasValue && 
               !IsCompleted && 
               DueDate.Value < dateTimeProvider.UtcNow;
    }

    /// <summary>
    /// 标记为删除并触发删除事件
    /// </summary>
    public void MarkAsDeleted(IDateTimeProvider dateTimeProvider)
    {
        // 在聚合根内部触发领域事件
        Raise(new TodoItemDeletedEvent(Id, UserId, Description, dateTimeProvider.UtcNow));
    }
}
